package aquerius

/**
 * @author: Yardena
 * @date: Jul 19, 2009 5:15:42 PM
 */

import Basic._

trait Schema extends Expressions {

  type InputType
  type ResultType[X]
  type TableType<:Table

  trait Table { self: TableType =>

    type RecordType <: Product

    trait Column[+T] extends (RecordType => T) {
      val table = self
      //todo name
//      def eval(in: InputType): ResultType[T]
    }

    type ColumnType[+X]  <: Column[X]

    type BoolColumnType <: ColumnType[Boolean]    with BoolExpressionType[RecordType]
    type IntColumnType  <: ColumnType[Int]        with IntExpressionType[RecordType]
    type StrColumnType  <: ColumnType[String]     with StrExpressionType[RecordType]

    def bool(f: RecordType => Boolean) : BoolColumnType
    def int (f: RecordType => Int)     : IntColumnType
    def str (f: RecordType => String)  : StrColumnType

    //--------------- QUERY -----------------
    type QueryType <: Query

    trait Query extends (InputType => ResultType[RecordType]) { QueryType =>
      val table: self.type = self
      val unary_~ = table
      def where(restriction: BoolExpressionType[RecordType]) = query(condition and restriction) //todo optimize
      val condition: BoolExpressionType[RecordType]
    }

    def query(condition: BoolExpressionType[RecordType]): QueryType
    def query: QueryType = query(true) //todo cache?
    def unary_~ = query

  }

  def from[T<:Table] (table: T) = table.query  //requires dependant compilation

}
